package com.xxiivv.mute; import java.io.FileReader; import javax.script.Invocable; import javax.script.ScriptEngine; import javax.script.ScriptEngineManager; import javax.script.ScriptException; public class Module { private String name, filename; private ScriptEngine engine; public Module(String name, String filename) { this.name = name; this.filename = filename; } public void initialize(Memory memory) { engine = new ScriptEngineManager().getEngineByName ("nashorn"); engine.put ("memory", memory); engine.put ("console", Console.Instance); try { engine.eval (new FileReader (this.filename)); } catch (Exception e) { System.err.printf ("Unexpected exception caught while evaluating module '%s' javascript file '%s': %s\n", name, filename, e); // e.printStackTrace(); } invoke ("init"); } public void reload(Memory memory) { close(); initialize(memory); } public void evaluate(Statement statement, Iterable<String> operations) { for (Value v : statement.getValues()) { String name = v.name.toString(); if (v.value instanceof Integer || v.value instanceof String) engine.put (name, v.value); else if (v.value instanceof Value[]) { ValueCollection vc = new ValueCollection((Value[]) v.value); if (vc.isArray()) engine.put (name, vc.asArray()); else engine.put (name, vc); } else throw new RuntimeException("Value of type " + v.value.getClass().getSimpleName() + " is not supported"); } if (!statement.testConditions()) return; for (String o : operations) { invoke (o, o + " is undefined or not a function for module <" + name + ">."); } } public void close() { invoke ("destroy"); } private void invoke (String function) { invoke (function, null); } private void invoke (String function, String errorMessage) { try { ((Invocable) engine).invokeFunction (function); } catch (ScriptException e) { System.err.printf ("{%s} in module <%s> threw an exception at line %s: '%s'\n", function, name, e.getLineNumber(), e.getCause().getMessage()); // e.printStackTrace (); } catch (Exception e) { if (errorMessage != null) System.err.println (errorMessage); } } public String getName() { return name; } }